package com.lz.security.filter;

import com.lz.security.pojo.LoginUser;
import com.lz.security.utils.JsonUtil;
import com.lz.security.utils.JwtUtil;
import com.lz.utils.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import org.springframework.util.StringUtils;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.ref.ReferenceQueue;

/**
 * 校验jwt过滤器
 */
@Slf4j
public class JwtTokenVerifyFilter extends BasicAuthenticationFilter {

    private final AuthenticationManager authenticationManager;

    /**
     * 调用父类有参构造,初始化身份认证管理器
     * @param authenticationManager
     */
    public JwtTokenVerifyFilter(AuthenticationManager authenticationManager) {
        super(authenticationManager);
        this.authenticationManager = authenticationManager;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
        /**
         * 校验jwt的思路
         * 1.从请求获取jwt字符串:请求头,请求参数
         * 2.判断字符串是否为空,是否为空字符串,是否不以指定的字符开头
         * 3.判断字符串是否过期
         */
        String token = request.getHeader("Authorization");
        log.info("**********token******,{}",token);
        if(!StringUtils.hasLength(token) || !token.startsWith("Bearer ")){
            chain.doFilter(request, response);
            //设置提示
            log.info("**********token******,{}",1);
            response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
            response.getWriter().write(JsonUtil.toString(Result.error(-10, "未登陆，请先登陆")));
        }else if(JwtUtil.isExpire(token.replace("Bearer ", ""))){
            log.info("**********token******,{}",2);
            chain.doFilter(request, response);
            //设置提示
            response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
            response.getWriter().write(JsonUtil.toString(Result.error(-10, "会话已过期，请重新登陆")));
        }else{
            log.info("**********token******,{}",3);
            //从jwt中获取登陆用户对象
            LoginUser loginUser = JwtUtil.getLoginUserByMobile(token.replace("Bearer ", ""));
            log.info("**********从jwt中获取登陆用户对象******,{}",loginUser.toString());
            UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(loginUser, null, loginUser.getAuthorities());
            //将UsernamePasswordAuthenticationToken放入Security上下文对象中
            SecurityContextHolder.getContext().setAuthentication(authRequest);
            chain.doFilter(request, response);
        }

    }
}
